package cn.wubo.vrr.help.controller;

import cn.wubo.vrr.help.entity.Gitstat;
import cn.wubo.vrr.help.entity.Person;
import cn.wubo.vrr.help.service.AttendanceResultService;
import cn.wubo.vrr.help.service.GitstatService;
import cn.wubo.vrr.help.service.LinkService;
import cn.wubo.vrr.help.service.PersonService;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Controller
public class IndexController {
    private final static Logger logger = LoggerFactory.getLogger(IndexController.class);
    @Autowired
    PersonService personService;
    @Autowired
    AttendanceResultService attendanceResultService;
    @Autowired
    LinkService linkService;
    @Autowired
    GitstatService gitstatService;

    /*@RequestMapping("/")
    public String index() {
        return "redirect:/list";
    }*/

    @RequestMapping("/")
    public String index() {
        return "redirect:/index";
    }

    @RequestMapping("/index")
    public String index(ModelMap map) {
        map.put("linkList", linkService.findAll());
        return "index";
    }

    //@RequestMapping("/list")
    public String list(ModelMap map) {
        map.put("personList", personService.findAll());
        return "list";
    }

    //@RequestMapping("/reslist")
    public String reslist(ModelMap map) {
        map.put("reslist", attendanceResultService.findAll());
        return "reslist";
    }

    //@RequestMapping("/create")
    public String create() {
        return "create";
    }

    //@RequestMapping("/save")
    public String save(@ModelAttribute Person p) {
        personService.save(p);
        return "redirect:/list";
    }

    //@RequestMapping("/delete/{id}")
    public String delete(@PathVariable(value = "id", required = true) Integer id) {
        personService.deleteById(id);
        return "redirect:/list";
    }

    //@RequestMapping("/ehrLogin")
    public String ehrLogin() {
        return "ehrLogin";
    }

    //@RequestMapping("/viewPage")
    public String viewPage(String page) {
        return page;
    }

    @Value("${custom.statsvn}")
    private String statsvnPath;

    @RequestMapping("/svnAnalyzeList")
    public String svnAnalyzeList(ModelMap map) {
        File doc = new File(statsvnPath);
        if (doc.exists() && doc.isDirectory()) {
            File[] docDates = doc.listFiles();
            List<Map<String, Object>> res = new ArrayList<>();
            for (File docDate : docDates) {
                if (docDate.isDirectory()) {
                    Map<String, Object> m = new HashMap<>(2);
                    m.put("title", docDate.getName());
                    m.put("url", "/statsvn/" + docDate.getName() + "/index.html");
                    res.add(m);
                }
            }
            map.put("reslist", res);
        }
        return "svnAnalyzeList";
    }

    @RequestMapping("/gitstatlist")
    public String gitstatlist(ModelMap map) {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        List<String> dateList = IntStream.range(0, 7).mapToObj(e -> {
            cal.add(Calendar.DATE, -e);
            String date = sdf.format(cal.getTime());
            cal.add(Calendar.DATE, e);
            return date;
        }).collect(Collectors.toList());

        Map<String, OnePerson> personData = new HashMap<>();

        List<Map<String, Object>> totalData = dateList.stream()
                .sorted(Collections.reverseOrder().reversed())
                .map(e -> {
                    Map<String, Object> m = new HashMap<>();
                    List<Gitstat> res = gitstatService.findAllByDateOrderByProjectAscAuthorAsc(e);
                    m.put("date", e);
                    m.put("all-add", res.stream().mapToLong(ee -> Long.parseLong(ee.getAddnum())).sum());
                    m.put("all-sub", res.stream().mapToLong(ee -> Long.parseLong(ee.getSubnum())).sum());
                    m.put("all-total", res.stream().mapToLong(ee -> Long.parseLong(ee.getTotalnum())).sum());

                    res.forEach(ee -> {
                        if (personData.containsKey(ee.getAuthor())) {
                            personData.put(ee.getAuthor(), personData.get(ee.getAuthor()).sumRecord(Long.parseLong(ee.getAddnum()), Long.parseLong(ee.getSubnum()), Long.parseLong(ee.getTotalnum())));
                        } else {
                            personData.put(ee.getAuthor(), new OnePerson(Long.parseLong(ee.getAddnum()), Long.parseLong(ee.getSubnum()), Long.parseLong(ee.getTotalnum())));
                        }
                    });

                    return m;
                }).collect(Collectors.toList());

        map.put("reslist", dateList.stream().map(e -> {
            Map<String, Object> m = new HashMap<>();
            if (gitstatService.existsByDate(e)) {
                m.put("date", e);
                m.put("url", "/gitstat/" + e);
            }
            return m;
        }).filter(e -> !e.isEmpty()).collect(Collectors.toList()));

        map.put("totalData", totalData);
        map.put("personData", personData);
        return "gitstatlist";
    }

    @Data
    public class OnePerson {
        private Long addsum;
        private Long subsum;
        private Long totalsum;

        public OnePerson() {
        }

        public OnePerson(Long addsum, Long subsum, Long totalsum) {
            this.addsum = addsum;
            this.subsum = subsum;
            this.totalsum = totalsum;
        }

        public OnePerson sumRecord(Long addsum, Long subsum, Long totalsum) {
            this.addsum += addsum;
            this.subsum += subsum;
            this.totalsum += totalsum;
            return this;
        }
    }

    @RequestMapping("/gitstat/{date}")
    public String gitstatdate(@PathVariable(value = "date") String date, ModelMap map) {
        List<Gitstat> gitstatList = gitstatService.findAllByDateOrderByProjectAscAuthorAsc(date);
        List<String> projectList = gitstatList.stream().map(Gitstat::getProject).distinct().collect(Collectors.toList());
        List<Map<String, Object>> rows = gitstatList.stream().map(Gitstat::getAuthor).distinct().map(e -> {
            Map<String, Object> m = new HashMap<>();
            m.put("author", e);
            projectList.forEach(ee -> {
                Gitstat one = gitstatList.stream().filter(eee -> eee.getAuthor().equals(e) && eee.getProject().equals(ee)).findAny().orElse(new Gitstat());
                m.put(ee + "-add", one.getAddnum());
                m.put(ee + "-sub", one.getSubnum());
                m.put(ee + "-total", one.getTotalnum());
            });
            return m;
        }).map(e -> {
            e.put("all-add", sumByCol("-add", e));
            e.put("all-sub", sumByCol("-sub", e));
            e.put("all-total", sumByCol("-total", e));
            return e;
        }).collect(Collectors.toList());
        map.put("reslist", rows);
        projectList.add("all");
        map.put("cols", projectList);
        return "gitstatdate";
    }

    private String sumByCol(String col, Map<String, Object> e) {
        return String.valueOf(e.entrySet().stream().filter(ee -> !ee.getKey().equals("author") && ee.getKey().endsWith(col) && !StringUtils.isEmpty(e.get(ee.getKey()))).mapToLong(ee -> Long.parseLong((String) e.get(ee.getKey()))).sum());
    }
}
